import 'package:dio/dio.dart';
import '../constants/api_constants.dart';

/// Dio网络客户端配置
class DioClient {
  late final Dio _dio;

  DioClient() {
    _dio = Dio(BaseOptions(
      baseUrl: ApiConstants.baseUrl,
      connectTimeout: ApiConstants.timeout,
      receiveTimeout: ApiConstants.timeout,
      headers: {
        'Content-Type': 'application/json',
        'Accept': 'application/json',
      },
    ));
    _configureDio();
  }

  void _configureDio() {
    // 添加拦截器
    _dio.interceptors.add(LogInterceptor(
      request: true,
      requestHeader: false,
      requestBody: false,
      responseHeader: false,
      responseBody: false,
      error: true,
    ));

    // 添加重试拦截器
    _dio.interceptors.add(RetryInterceptor(
      dio: _dio,
      logPrint: print,
      retries: ApiConstants.maxRetries,
      retryDelays: [
        ApiConstants.retryDelay,
        ApiConstants.retryDelay * 2,
        ApiConstants.retryDelay * 3,
      ],
    ));

    // 添加错误处理拦截器
    _dio.interceptors.add(ErrorInterceptor());
  }

  Dio get dio => _dio;
}

/// 重试拦截器
class RetryInterceptor extends Interceptor {
  final Dio dio;
  final Function(dynamic) logPrint;
  final int retries;
  final List<Duration> retryDelays;

  const RetryInterceptor({
    required this.dio,
    required this.logPrint,
    required this.retries,
    required this.retryDelays,
  });

  @override
  void onError(DioException err, ErrorInterceptorHandler handler) async {
    // 只对特定错误进行重试
    if (_shouldRetry(err)) {
      final retryCount = err.requestOptions.extra['retry_count'] ?? 0;
      
      if (retryCount < retries) {
        err.requestOptions.extra['retry_count'] = retryCount + 1;
        
        // 等待一段时间后重试
        await Future.delayed(retryDelays[retryCount]);
        
        try {
          final response = await dio.fetch(err.requestOptions);
          handler.resolve(response);
          return;
        } catch (e) {
          // 重试失败，继续处理错误
        }
      }
    }
    
    handler.next(err);
  }

  bool _shouldRetry(DioException err) {
    // 网络连接错误或服务器错误才重试
    return err.type == DioExceptionType.connectionTimeout ||
           err.type == DioExceptionType.receiveTimeout ||
           err.type == DioExceptionType.sendTimeout ||
           (err.response?.statusCode != null && 
            err.response!.statusCode! >= 500);
  }
}

/// 错误处理拦截器
class ErrorInterceptor extends Interceptor {
  @override
  void onError(DioException err, ErrorInterceptorHandler handler) {
    String message = '网络请求失败';
    
    switch (err.type) {
      case DioExceptionType.connectionTimeout:
      case DioExceptionType.sendTimeout:
      case DioExceptionType.receiveTimeout:
        message = '连接超时，请检查网络';
        break;
      case DioExceptionType.badResponse:
        message = _handleStatusCode(err.response?.statusCode);
        break;
      case DioExceptionType.cancel:
        message = '请求已取消';
        break;
      case DioExceptionType.unknown:
        if (err.message?.contains('SocketException') == true) {
          message = '网络连接失败，请检查网络设置';
        } else {
          message = '未知错误：${err.message}';
        }
        break;
      default:
        message = '网络请求失败：${err.message}';
    }
    
    // 创建自定义错误
    final customError = DioException(
      requestOptions: err.requestOptions,
      response: err.response,
      type: err.type,
      error: message,
      message: message,
    );
    
    handler.next(customError);
  }

  String _handleStatusCode(int? statusCode) {
    switch (statusCode) {
      case 400:
        return '请求参数错误';
      case 401:
        return '未授权访问';
      case 403:
        return '访问被拒绝';
      case 404:
        return '请求的资源不存在';
      case 429:
        return '请求过于频繁，请稍后再试';
      case 500:
        return '服务器内部错误';
      case 502:
        return '网关错误';
      case 503:
        return '服务暂时不可用';
      default:
        return '服务器错误($statusCode)';
    }
  }
} 